package com.alibaba.cirtus.ots.application.adapter.ability.facade.service.retry;

import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.otsapplicationadaptersdk.invoiceretrywrite.dto.FindLatestAndRetryRequest;
import com.epoch.app.otsapplicationadaptersdk.invoiceretrywrite.dto.FindLatestAndRetryResponse;
import com.epoch.app.otsapplicationadaptersdk.invoiceretrywrite.service.InvoiceRetryWriteService;
import com.epoch.app.otsapplicationadaptersdk.model.dto.InvoiceRetryEntity;
import com.epoch.app.otsapplicationadaptersdk.model.dto.InvoiceTrailQueryRequest;
import com.epoch.app.otsapplicationadaptersdk.model.dto.InvoiceTrailQueryResponse;
import com.epoch.app.otsapplicationadaptersdk.model.dto.MessageHeaderSDO;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapCommResponse;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapCommSDO;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf016Request;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf016SDO;
import com.epoch.app.otsapplicationadaptersdk.sap.mnsapif016.service.MnSapIf016Service;
import com.epoch.app.otsapplicationadaptersdk.service.OtsApplicationAdapterSdkService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
@Primary
public class InvoiceRetryWriteServiceImpl implements InvoiceRetryWriteService {
    private Log log = Log.getLogger(InvoiceRetryWriteServiceImpl.class);
    @Resource
    private OtsApplicationAdapterSdkService otsApplicationAdapterSdkService;
    @Resource
    private MnSapIf016Service mnSapIf016Service;
    @Override
    public FindLatestAndRetryResponse findLatestAndRetry(FindLatestAndRetryRequest findLatestAndRetryRequest){
        if (Objects.isNull(findLatestAndRetryRequest)&&CollectionUtils.isEmpty(findLatestAndRetryRequest.getInvoiceIds())){
            return FindLatestAndRetryResponse.builder().message("重试发票号不能为空").build();
        }

        List invoiceIds = findLatestAndRetryRequest.getInvoiceIds();
        List<MnSapIf016SDO> needProcessData=new ArrayList<>();
        for (Object invoiceIdObj : invoiceIds) {
            String invoiceId = String.valueOf(invoiceIdObj);

            InvoiceTrailQueryRequest invoiceTrailQueryRequest = new InvoiceTrailQueryRequest();
            invoiceTrailQueryRequest.setInvoiceId(invoiceId);
            InvoiceTrailQueryResponse invoiceTrailQueryResponse = otsApplicationAdapterSdkService.invoiceTrailQuery(invoiceTrailQueryRequest);
            MnSapIf016Request mnSapIf016Request=new MnSapIf016Request();
            MnSapCommResponse mnSapIf016Result=new MnSapCommResponse();
            if (Objects.nonNull(invoiceTrailQueryResponse)&& CollectionUtils.isNotEmpty(invoiceTrailQueryResponse.getResult())){
                InvoiceRetryEntity invoiceRetryEntity = invoiceTrailQueryResponse.getResult().get(0);
                String input = invoiceRetryEntity.getInput();
                if (StringUtils.isNotBlank(input)){
                    JSONObject jsonObject = JSONObject.parseObject(input);
                    String data = jsonObject.getString("body");
                    if (StringUtils.isNotBlank(data)){
                        mnSapIf016Request = JSONObject.parseObject(data, MnSapIf016Request.class);
                    }
                }
                String output = invoiceRetryEntity.getOutput();
                if (StringUtils.isNotBlank(output)){
                    mnSapIf016Result= JSONObject.parseObject(output, MnSapCommResponse.class);
                }
            }
            List<MnSapIf016SDO> inputCollect = Nullable.stream(mnSapIf016Request.getData()).filter(o -> invoiceId.equals(o.getInvoiceId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(inputCollect)){
                continue;
            }
            MnSapIf016SDO effectInput = inputCollect.get(0);
            int shouldProcessSize = effectInput.getItems().size();
            List<MnSapCommSDO> effectResult = Nullable.stream(mnSapIf016Result.getData()).filter(o -> invoiceId.equals(o.getHeaderKey())).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(effectResult)||CollectionUtils.isEmpty(effectResult.get(0).getItem())||effectResult.get(0).getItem().size()<shouldProcessSize){
                needProcessData.add(effectInput);
            }

        }

        MnSapIf016Request mnSapIf016Request = new MnSapIf016Request();
        MessageHeaderSDO messageHeader = MessageHeaderSDO.builder().messageId("invoiceManuelRetry")
                .interfacePath("SI_ECC_Invoice_Receive_Asyn_Out").receiver("ORZT").sender("ECC")
                .sendTime(currentDateTime()).build();
        mnSapIf016Request.setMessageHeader(messageHeader);
        mnSapIf016Request.setData(needProcessData);

        log.info("manuel retry sap invoice request:"+JSONObject.toJSONString(mnSapIf016Request));
        MnSapCommResponse mnSapCommResponse = mnSapIf016Service.externalSyncInvoice(mnSapIf016Request);
        log.info("manuel retry sap invoice response:"+JSONObject.toJSONString(mnSapCommResponse));
        InvoiceRetryEntity result=InvoiceRetryEntity.builder().input(JSONObject.toJSONString(mnSapIf016Request))
                .output(JSONObject.toJSONString(mnSapCommResponse)).build();

        return FindLatestAndRetryResponse.builder().success(Boolean.TRUE).result(Lists.newArrayList(result)).total(1).build();
    }

    private String currentDateTime(){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");
        String format = simpleDateFormat.format(new Date());
        return format;
    }
}
